package descentFly.away3D4.Generator
{
	import UIFree.ObjectEvent;
	
	import away3d.containers.ObjectContainer3D;
	import away3d.entities.Mesh;
	import away3d.materials.BitmapMaterial;
	import away3d.materials.ColorMaterial;
	import away3d.materials.MaterialBase;
	import away3d.materials.SkyBoxMaterial;
	import away3d.materials.methods.EnvMapMethod;
	import away3d.primitives.SkyBox;
	import away3d.primitives.Sphere;
	import away3d.tools.utils.Bounds;
	
	import descentFly.away3D4.Generator.ENV02.df_fantasticPlane;
	import descentFly.away3D4.df_awaySpace;
	import descentFly.away3D4.df_baseSpaceElement;
	import descentFly.away3D4.df_loadSection;
	import descentFly.data.df_fields;
	import descentFly.df_utils;
	
	import flash.geom.Matrix;
	import flash.geom.Matrix3D;
	import flash.geom.Vector3D;
	
	import jiglib.geometry.JSphere;
	import jiglib.physics.RigidBody;
	import jiglib.plugin.away3d4.Away3D4Mesh;
	
	public class df_envGenerator extends df_baseParser {
		private var _elems		: ObjectContainer3D;
		private var _bodys		: Array;
		private var _surface	: int;
		
		public function df_envGenerator(a_space:df_awaySpace, a_options:Object) {
			super(a_space, a_options);
			_surface = 0;
			_elems 	= new ObjectContainer3D();
			_bodys	= new Array();
			Space.view.view.scene.addChild(_elems);
		}
		
		protected function parseMap(map: Array): Array {
			map.forEach(function(item: String, i: int, arr: Array): void {
				var a: Array = item.split(',');
				map[i] = {
					x: parseFloat(a[0]),
					y: parseFloat(a[1]),
					size: parseFloat(a[2]),
					color: parseInt(a[3], 16)
				}
			});
			return map;
		}
		
		override protected function parseElement(m: Mesh): void {
			var map: Array = parseMap(options.surfaces[_surface].spots);
			var mat: Matrix3D;
			var material: BitmapMaterial = new BitmapMaterial(df_fantasticPlane.bmdGenarate(1024, 1024, map, 100));
			
			material.alphaBlending 	= true;
			material.bothSides 		= true;
			m.material = material;
			
			_elems.addChild(m);
			
			Bounds.getMeshBounds(m);
			mat = m.transform.clone();
			mat.appendTranslation(Bounds.minX, Bounds.minY, Bounds.maxZ);
			
			if (options.surfaces[_surface].spheres) {
				map = parseMap(options.surfaces[_surface].spheres);
				
				var ls: df_loadSection = new df_loadSection();
				var skyBox: SkyBox = ls.loadSkyBox(options.sphereEnvURL);
				
				ls.endSection(function(): void {
					var clMat: ColorMaterial = new ColorMaterial(0xFFF000, 1);
					clMat.addMethod(new EnvMapMethod((skyBox.material as SkyBoxMaterial).cubeMap));
						
					
					spheresGenerate(mat.clone(), Bounds.width, 300, map, clMat);
				});
			}
			
			if (options.surfaces[_surface].elements) {
				options.surfaces[_surface].elements.forEach(function(item: Object, i: int, arr: Array): void {
					var mat: Matrix3D = m.transform.clone();
					mat.appendTranslation(Bounds.minX, Bounds.minY, Bounds.maxZ);
					var points: Array = parseMap(item.points);
					points.forEach(function(point: Object, i: int, arr: Array): void {
						createElement(mat.clone(), point, item.element, Bounds.width);
					});
				})
			}
			
			_surface++;
		}
		
		public function spheresGenerate(mat: Matrix3D, mapSize: Number, 
											   elemSize: Number, map: Array, material: MaterialBase): void {
			map.forEach(function(item: Object, i: int, arr: Array): void {
				var radius: Number = item.size * elemSize;
				var sphere: Sphere = new Sphere(material, radius);
				_elems.addChild(sphere);
				
				var jsphere: JSphere = new JSphere(new Away3D4Mesh(sphere), radius);
				_bodys.push(jsphere);
				Space.physic.addBody(jsphere);
				jsphere.movable = false;
				//				var sphere: Sphere = new Sphere(material, item.size * elemSize);
				var sMat: Matrix3D = mat.clone();
				sMat.appendTranslation(item.x * mapSize, 0, -item.y * mapSize);
				jsphere.moveTo(sMat.transformVector(new Vector3D()));
			});
		}
		
		protected function createElement(mat: Matrix3D, point: Object, element: Object, mapSize: Number): void {
			var sMat: Matrix3D = mat.clone();
			sMat.appendTranslation(point.x * mapSize, 0, -point.y * mapSize);
			new (element.Class)(sMat, Space, element.options);
		}
		
		override public function dispose():void {
			_elems.dispose(true);
			_bodys.forEach(function(body: RigidBody, i: int, arr: Array): void {
				Space.physic.removeBody(body);
			});
			super.dispose();
		}
	}
}